﻿// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
// Website: https://admin.blazor.zone

using BlazorAdmin.Models;
using BlazorAdmin.Interface;
using BootstrapBlazor.Components;
using BlazorAdmin.Web.Shared.Extensions;
using BlazorAdmin.Web.Shared.Providers;
using BlazorAdmin.Web.Shared.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Routing;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;

namespace Pangeo.Admin.Web.Shared
{
    /// <summary>
    /// 主窗体
    /// </summary>
    public partial class AdminLayout : IDisposable
    {
        internal const string LayoutKey_Title = "title";
        internal const string LayoutKey_Footer = "footer";
        internal const string LayoutKey_DisplayName = "displayName";
        private const int LockInterval = 100 * 1000;
        private readonly bool AppIsLock;
        [NotNull] private User? currentUser = null;
        private IEnumerable<MenuItem>? menuItems;
        private string webTitle = string.Empty;
        private string webFooter = string.Empty;
        private string firstUrl = string.Empty;

        [CascadingParameter(Name = "AppInfo")]
        public SysInfo? AppInfo { get; set; }

        #region Inject
        [Inject]
        [NotNull]
        private IDict? DictService { get; set; }
        [Inject]
        [NotNull]
        private IUser? UserService { get; set; }
        [Inject]
        [NotNull]
        private INavigation? NavigationsService { get; set; }
        [Inject]
        [NotNull]
        private NavigationManager? NavigationManager { get; set; }
        [Inject]
        [NotNull]
        private AuthenticationStateProvider? AuthProvider { get; set; }
        [Inject]
        [NotNull]
        private BootstrapAppContext? AppContext { get; set; }
        #endregion

        #region override
        /// <summary>
        /// 
        /// </summary>
        protected override void OnInitialized()
        {
            currentUser = AppContext.CurrentUser;
            if (null == currentUser)
                return;
            ClientApp app = DictService.GetClient(AppContext.AppID);
            string? userName = currentUser.UserName;
            currentUser.Icon = string.IsNullOrEmpty(currentUser.Icon) ? $"{SysConsts.WwwRoot}/images/uploader/default.jpg" : GetIcon(currentUser.Icon);
            menuItems = NavigationsService.GetAllMenus(userName).ToMenus();
            webTitle = app.Title;
            webFooter = app.Footer;
            AppContext.BaseUri = NavigationManager.ToAbsoluteUri(NavigationManager.BaseUri);
            NavigationManager.LocationChanged += NavigationManager_LocationChanged;
        }

        private string GetIcon(string icon)
        {
            if (icon.Contains("://", StringComparison.OrdinalIgnoreCase) || icon.Contains(SysConsts.WwwRoot))
                return icon;
            else
                return string.Format("{0}{1}", DictService.GetIconFolderPath(), icon);
        }

        private void NavigationManager_LocationChanged(object? sender, LocationChangedEventArgs e)
        {
            Debug.WriteLine($"{sender} - {e.Location}", "NavigationManager_LocationChanged");
        }
        #endregion

        #region private methods
        private Task<bool> OnAuthorizing(string url)
        {
            //判断token是否过期，校验权限
            //SecurityService.AuhorizingNavigation(Context.UserName, NavigationManager.ToBaseRelativePath(url));
            //if (AuthProvider is AuthenticationProvider authProvider)
            //{
            //    var authState = authProvider.GetAuthenticationStateAsync().Result;
            //    if (authState.User != null && authState.User.Identity.IsAuthenticated)
            //    {
            //        return Task.FromResult(false);
            //    }
            //    else
            //    {
            //        //判断路径权限
            //        var allUrl = NavigationManager.ToBaseRelativePath(url);
            //    }
            //}
            return Task.FromResult(true);
        }

        /// <summary>
        /// 
        /// </summary>
        public Task OnUpdateAsync(string key)
        {
            switch (key)
            {
                case LayoutKey_DisplayName: currentUser = UserService.GetUserByUserName(currentUser?.UserName); break;
                default: return Task.FromResult(false);
            }
            StateHasChanged();
            return Task.CompletedTask;
        }
        private void OnLogout()
        {
            if (AuthProvider is AuthenticationProvider authProvider)
            {
                AppContext.CurrentUser = null;
                authProvider.MarkUserAsLoggedOut();
            }
        }

        private string GetDefaultUrl(string returnUrl, string? appId, IUser userService, IDict dictService)
        {
            string? userName = AppContext.LoginName;
            string? defaultAppId = AppContext.AppID;
            Uri? baseUri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
            string? schema = baseUri.Scheme;
            string? host = baseUri.Host;
            appId ??= userService.GetAppIdByUserName(userName) ?? defaultAppId;
            if (!string.IsNullOrEmpty(appId))
            {
                string? appUrl = dictService.GetHomeUrlByAppId(appId);
                if (!string.IsNullOrEmpty(appUrl))
                    returnUrl = $"{string.Format(appUrl, schema, host).TrimEnd('/')}/Admin/Index";
            }
            else
                returnUrl = "/Admin/Index";

            return returnUrl;
        }
        #endregion

        #region IDisposable
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                NavigationManager.LocationChanged -= NavigationManager_LocationChanged;
            }
        }
        #endregion
    }
}
